//
//  SFCRevision.m
//  SVNForCocoa
//
//  Created by Jeremy Pereira on 12/11/2013.
//  Copyright (c) 2013 Jeremy Pereira. All rights reserved.
//

#import "SFCRevision.h"
#import "SFCLib+Internals.h"


@implementation SFCRevision
{
    svn_opt_revision_t optRevision;
    bool optRevisionLegal;
}

-(enum svn_opt_revision_kind) kind
{
    return svn_opt_revision_unspecified;
}

+(SFCRevision*) unspecified
{
    return [[SFCRevision alloc] init];
}

+(SFCRevision*) number: (SFCRevNum) aNumber
{
	return [[SFCNumericalRevision alloc] initWithNumber: aNumber];
}


+(SFCRevision*) committed
{
    return [[SFCCommittedRevision alloc] init];
}

+(SFCRevision*) previous
{
    return [[SFCPreviousRevision alloc] init];
}

+(SFCRevision*) base
{
    return [[SFCBaseRevision alloc] init];
}

+(SFCRevision*) working
{
    return [[SFCWorkingRevision alloc] init];
}

+(SFCRevision*) head
{
    return [[SFCHeadRevision alloc] init];
}


-(SFCRevNum) number
{
    return -1;
}

+(SFCRevision*) date: (NSDate*) aDate
{
	return [[SFCDateRevision alloc] initWithDate: aDate];
}

-(NSDate*) date
{
    return nil;
}

-(const svn_opt_revision_t*) svnOptRevision
{
    if (!optRevisionLegal)
    {
        optRevision.kind = [self kind];
        if ([self number] != -1)
        {
            optRevision.value.number = [self number];
        }
        if ([self date] != nil)
        {
            optRevision.value.date = [[self date] aprTime];
        }
        optRevisionLegal = true;
    }
    return &optRevision;
}

-(NSString*) description
{
    return @"unspecified";
}

@end

@implementation SFCNumericalRevision
{
    SFCRevNum _number;
}

-(id) init
{
    return [self initWithNumber: 0];
}

-(id) initWithNumber: (SFCRevNum) aNumber
{
    self = [super init];
    if (self != nil)
    {
        _number = aNumber;
    }
    return self;
}


-(enum svn_opt_revision_kind) kind
{
    return svn_opt_revision_number;
}


-(SFCRevNum) number
{
    return _number;
}

-(NSString*) description
{
    return [NSString stringWithFormat: @"%ld", (long) [self number]];
}

@end

@implementation SFCDateRevision
{
    NSDate* _date;
}

-(id) init
{
    return [self initWithDate: [NSDate date]];
}

-(id) initWithDate: (NSDate*) aDate
{
    self = [super init];
    if (self != nil)
    {
        _date = aDate;
    }
    return self;
}

-(enum svn_opt_revision_kind) kind
{
    return svn_opt_revision_date;
}


-(NSDate*) date
{
    return _date;
}


-(NSString*) description
{
    return [NSString stringWithFormat: @"<%@>", [self date]];
}


@end

@implementation SFCCommittedRevision

-(enum svn_opt_revision_kind) kind
{
    return svn_opt_revision_committed;
}

-(NSString*) description
{
    return @"committed";
}

@end


@implementation SFCBaseRevision

-(enum svn_opt_revision_kind) kind
{
    return svn_opt_revision_base;
}


-(NSString*) description
{
    return @"BASE";
}


@end

@implementation SFCPreviousRevision

-(enum svn_opt_revision_kind) kind
{
    return svn_opt_revision_previous;
}

-(NSString*) description
{
    return @"previous";
}

@end

@implementation SFCWorkingRevision

-(enum svn_opt_revision_kind) kind
{
    return svn_opt_revision_working;
}


-(NSString*) description
{
    return @"working";
}


@end

@implementation SFCHeadRevision

-(enum svn_opt_revision_kind) kind
{
    return svn_opt_revision_head;
}

-(NSString*) description
{
    return @"HEAD";
}

@end

@implementation SFCRevisionRange
{
    svn_opt_revision_range_t svnRevisionRange;
    bool revisionRangeLegal;
}

@synthesize start = _start;
@synthesize end = _end;

-(id) init
{
    return [self initFrom: [SFCRevision number: 0] to: [SFCRevision head]];
}

-(id) initFrom: (SFCRevision*) newStart to: (SFCRevision*) newEnd
{
	self = [super init];
    if (self != nil)
    {
        _start = newStart;
        _end = newEnd;
    }
    return self;
}

+(SFCRevisionRange*) rangeFrom: (SFCRevision*) start to: (SFCRevision*) end
{
	return [[[self class] alloc] initFrom: start to: end];
}

-(const svn_opt_revision_range_t*) svnRevisionRange
{
	if (!revisionRangeLegal)
    {
        svnRevisionRange.start = *[[self start] svnOptRevision];
        svnRevisionRange.end   = *[[self end] svnOptRevision];
        revisionRangeLegal = true;
    }
    return &svnRevisionRange;
}

-(NSString*) description
{
    return [NSString stringWithFormat: @"%@:%@", [self start], [self end]];
}

@end
